package com.itcast.yygh.orders.receiver;

import com.itcast.yygh.model.enums.OrderStatusEnum;
import com.itcast.yygh.model.model.order.OrderInfo;
import com.itcast.yygh.model.vo.msm.MsmVo;
import com.itcast.yygh.model.vo.order.OrderMqVo;
import com.itcast.yygh.orders.service.OrderService;
import com.itcast.yygh.rabbit.Const.MqConst;
import com.itcast.yygh.rabbit.service.RabbitService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
import com.rabbitmq.client.Channel;
import java.util.Map;
//监听延迟队列
@Slf4j
@Component
public class OrderDelayReceiver {

    @Autowired
    private OrderService orderService;

    @Autowired
    private RabbitService rabbitService;

    // 使用Redis实现消费幂等性
    @Autowired
    private RedisTemplate redisTemplate;

    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "exchange.direct.order", durable = "true"),
            exchange = @Exchange(value = "exchange.direct.order"),
            key = {"order"}
    ))
    public void receiver(Map<String, Object> map, Message message, Channel channel) {
        String messageId = message.getMessageProperties().getMessageId();

        try {
            // 幂等性检查
            String redisKey = "consumed_message:" + messageId;
            Boolean hasConsumed = redisTemplate.hasKey(redisKey);
            if (Boolean.TRUE.equals(hasConsumed)) {
                log.info("消息已消费，忽略重复消息: {}", messageId);
                channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
                return;
            }

            Long orderId =  Long.valueOf(map.get("orderId").toString());
            String scheduleId = (String) map.get("scheduleId");

            // 查询订单状态
            OrderInfo orderInfo = orderService.getById(orderId);

            // 如果订单未支付，则自动取消
            if (orderInfo != null && orderInfo.getOrderStatus().intValue() == OrderStatusEnum.UNPAID.getStatus().intValue()) {
                log.info("自动取消超时未支付订单，订单ID: {}", orderId);

                // 更新订单状态为取消
                orderInfo.setOrderStatus(OrderStatusEnum.CANCLE.getStatus());
                orderService.updateById(orderInfo);

                // 发送消息更新预约数（可预约数加1）
                OrderMqVo orderMqVo = new OrderMqVo();
                orderMqVo.setScheduleId(scheduleId);

                // 发送短信通知
                MsmVo msmVo = new MsmVo();
                msmVo.setPhone(orderInfo.getPatientPhone());
                orderMqVo.setMsmVo(msmVo);

                rabbitService.sendMessage(MqConst.EXCHANGE_DIRECT_ORDER, MqConst.ROUTING_ORDER, orderMqVo);

                // 标记消息已消费
                redisTemplate.opsForValue().set(redisKey, "1", 24, TimeUnit.HOURS);
            }

            // 手动确认消息
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            log.error("处理延迟订单消息失败", e);
            try {
                // 拒绝消息并重新入队
                channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
            } catch (Exception ex) {
                log.error("消息拒绝失败", ex);
            }
        }
    }
}
